//  Brett Jones
//  PBR Senior Thesis
//  Copyright Brett Jones October 2007

using System;
using System.Collections;
using System.Collections.Generic;
using System.Text;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Xml;

namespace PBR
{
    /// <summary>
    /// A Layer consists of 3 images, the color, spec-map and height-map
    /// </summary>
    public class Layer: IDisposable, IConvertToXml
    {
        #region Constant Variables

        private const double GAUSSIANBLURWIDTH = 15.0;

        #endregion

        #region Member Variables

        // Bitmaps
        public BitmapUnsafe ColorImage;
        public BitmapUnsafe SpecularImage;
        public BitmapUnsafe HeightImage;
        public BitmapUnsafe PaintImage;
        public BitmapUnsafe SpecResultImage;
        public BitmapUnsafe AnglesImage;
        public BitmapUnsafe VectorImage;
        public BitmapUnsafe EdgesImage;
        public BitmapUnsafe BlurredColorImage;
        public BitmapUnsafe SegmentsImage;
        public BitmapUnsafe RenderImage;
        public Bitmap ConnectedComponentsImage;
        public Bitmap OverlayImage;

        // Manual stroke edit stuff
        public Stroke SelectedStroke;

        // Tier
        public Tier ImageTier;

        // Vectors Data
        //private KDTreeDLL.KDTree vectorsKDTree;
        //private List<KDNodeData> vectorsList;
        public KDNodeData SelectedVector;
        public ArrayList EdgePixels;

        /// <summary>
        /// List of image segments in the source image
        /// </summary>
        public ArrayList segments;


        public int[,] ObjectLabels;
        public Stroke[,] StrokeArray;

        public string Name;

        #endregion

        #region Member Functions

        public Layer(string colorName, string specName, string heightName,
            string blankName, string segmentsName, string name, Scene scene)
        {
            // Bitmap Elements
            ColorImage = new BitmapUnsafe(XMLSchema.ColorImage, colorName);
            SpecularImage = new BitmapUnsafe(XMLSchema.SpecularImage, specName);
            HeightImage = new BitmapUnsafe(XMLSchema.HeightImage, heightName);
            PaintImage = new BitmapUnsafe("PaintImage", ColorImage);
            SpecResultImage = new BitmapUnsafe(blankName);
            AnglesImage = new BitmapUnsafe(blankName);
            VectorImage = new BitmapUnsafe(blankName);
            RenderImage = new BitmapUnsafe(blankName);
            OverlayImage = new Bitmap(blankName);
            
            
            // load grayscale edges image
            SegmentsImage = new BitmapUnsafe("Segments", segmentsName);
            AForge.Imaging.Filters.GrayscaleBT709 grayscaleFilter = new AForge.Imaging.Filters.GrayscaleBT709();
            SegmentsImage.Bitmap = grayscaleFilter.Apply(SegmentsImage.Bitmap);
            
            EdgesImage = new BitmapUnsafe(blankName);
            
            BlurredColorImage = new BitmapUnsafe("Blurred", ColorImage);
            ConnectedComponentsImage = new Bitmap(blankName);

            ImageTier = new Tier(ColorImage.Bitmap, SegmentsImage.Bitmap);

            EdgePixels = new ArrayList();

            //vectorsKDTree = new KDTreeDLL.KDTree(2);
            //vectorsList = new List<KDNodeData>();

            // Generate Edges Image
            //AForge.Imaging.Filters.SobelEdgeDetector sobelEdgeDetector = new AForge.Imaging.Filters.SobelEdgeDetector();
            //edgesImage.Bitmap = sobelEdgeDetector.Apply(mColor.Bitmap);

            // Generate Blurred Image
            //AForge.Imaging.Filters.GaussianBlur gaussianBlur = new AForge.Imaging.Filters.GaussianBlur(GAUSSIANBLURWIDTH);
            //blurredImage.Bitmap = gaussianBlur.Apply(mColor.Bitmap);

            // Vectors Data
            
            Name = name;

            // Empty list of all current segments
            segments = new ArrayList();

            ObjectLabels = new int[ColorImage.Width, ColorImage.Height];
            StrokeArray = new Stroke[ColorImage.Width, ColorImage.Height];
        }

        /// <summary>
        /// Disposes of the BitmapUnsafe objects
        /// </summary>
        ~Layer()
        {
            ColorImage.Dispose();
            SpecularImage.Dispose();
            HeightImage.Dispose();
            PaintImage.Dispose();
            SpecResultImage.Dispose();
            AnglesImage.Dispose();
            VectorImage.Dispose();
            EdgesImage.Dispose();
            BlurredColorImage.Dispose();
            SegmentsImage.Dispose();
        }

        /// <summary>
        /// Disposes of the BitmapUnsafe objects
        /// </summary>
        public void Dispose()
        {
            ColorImage.Dispose();
            SpecularImage.Dispose();
            HeightImage.Dispose();
            PaintImage.Dispose();
            SpecResultImage.Dispose();
            AnglesImage.Dispose();
            VectorImage.Dispose();
            EdgesImage.Dispose();
            BlurredColorImage.Dispose();
            SegmentsImage.Dispose();
        }

        public void ConvertToXml(XmlElement root, XmlDocument doc)
        {
            XmlElement layer = doc.CreateElement(XMLSchema.Layer);
            layer.SetAttribute(XMLSchema.LayerName, Name);

            ColorImage.ConvertToXml(layer, doc);
            SpecularImage.ConvertToXml(layer, doc);
            HeightImage.ConvertToXml(layer, doc);

            root.AppendChild(layer);
        }

        #endregion
        
        #region Depricated Properties

        ///// <summary>
        ///// 
        ///// </summary>
        //public BitmapUnsafe ColorImage
        //{
        //    get { return colorImage; }
        //    set { colorImage = value; }
        //}

        //public BitmapUnsafe SpecularImage
        //{
        //    get
        //    {
        //        return specularImage;
        //    }
        //    set
        //    {
        //        specularImage = value;
        //    }
        //}

        //public BitmapUnsafe HeightImage
        //{
        //    get
        //    {
        //        return heightImage;
        //    }
        //    set
        //    {
        //        heightImage = value;
        //    }
        //}

        //public BitmapUnsafe PaintImage
        //{
        //    get
        //    {
        //        return paintImage;
        //    }
        //    set
        //    {
        //        paintImage = value;
        //    }
        //}

        //public BitmapUnsafe SpecResultImage
        //{
        //    get
        //    {
        //        return mSpecResult;
        //    }
        //    set
        //    {
        //        mSpecResult = value;
        //    }
        //}

        //public BitmapUnsafe HeightResultImage
        //{
        //    get
        //    {
        //        return mHeightResult;
        //    }
        //    set
        //    {
        //        mHeightResult = value;
        //    }
        //}

        //public BitmapUnsafe AnglesImage
        //{
        //    get
        //    {
        //        return anglesImage;
        //    }
        //    set
        //    {
        //        anglesImage = value;
        //    }
        //}

        //public BitmapUnsafe VectorImage
        //{
        //    get
        //    {
        //        return vectorImage;
        //    }
        //    set
        //    {
        //        vectorImage = value;
        //    }
        //}

        //public BitmapUnsafe EdgesImage
        //{
        //    get
        //    {
        //        return edgesImage;
        //    }
        //    set
        //    {
        //        edgesImage = value;
        //    }
        //}

        //public BitmapUnsafe BlurredColorImage
        //{
        //    get
        //    {
        //        return blurredColorImage;
        //    }
        //    set
        //    {
        //        blurredColorImage = value;
        //    }
        //}

        ////public BitmapUnsafe ColorBlurred
        ////{
        ////    get
        ////    {
        ////        return colorBlurred;
        ////    }
        ////    set
        ////    {
        ////        colorBlurred = value;
        ////    }
        ////}

        //public Material Material
        //{
        //    get
        //    {
        //        return mMaterial;
        //    }
        //    set
        //    {
        //        mMaterial = value;
        //    }
        //}

        //public string Name
        //{
        //    get
        //    {
        //        return mName;
        //    }
        //    set
        //    {
        //        mName = value;
        //    }
        //}

        ////public KDTreeDLL.KDTree VectorsKDTree
        ////{
        ////    get
        ////    {
        ////        return vectorsKDTree;
        ////    }
        ////    set
        ////    {
        ////        vectorsKDTree = value;
        ////    }
        ////}

        ////public List<KDNodeData> VectorsList
        ////{
        ////    get
        ////    {
        ////        return vectorsList;
        ////    }
        ////    set
        ////    {
        ////        vectorsList = value;
        ////    }

        ////}

        //public KDNodeData SelectedVector
        //{
        //    get
        //    {
        //        return selectedVector;
        //    }
        //    set
        //    {
        //        selectedVector = value;
        //    }
        //}

        //public ArrayList EdgePixels
        //{
        //    get
        //    {
        //        return edgePixels;
        //    }
        //    set
        //    {
        //        edgePixels = value;
        //    }
        //}

        //public Bitmap ConnectedComponentsImage
        //{
        //    get { return connectedComponentsImage; }
        //    set { connectedComponentsImage = value; }
        //}

        //public BitmapUnsafe SegmentsImage
        //{
        //    get { return segmentsImage; }
        //    set { segmentsImage = value; }
        //}

        //public Bitmap VectorDisplayImage
        //{
        //    get { return vectorDisplayImage; }
        //    set { vectorDisplayImage = value; }
        //}

        #endregion
    }
}
